﻿using SketchUpAPI.NET.SketchUp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace SketchUpAPI.NET.Objects
{
    [StructLayout(LayoutKind.Sequential, Pack = 8)]
    public struct Point3D
    {
        public static Point3D Origin
        {
            get
            {
                return new Point3D(0, 0, 0);
            }
        }

        public double X { get; set; }
        public double Y { get; set; }
        public double Z { get; set; }

        public Point3D(double x, double y, double z)
        {
            this.X = x;
            this.Y = y;
            this.Z = z;
        }

        /// <summary>
        /// 两点距离
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public double DistanceTo(Point3D other)
        {
            return Math.Sqrt(Math.Pow(other.X - this.X, 2) + Math.Pow(other.Y - this.Y, 2) + Math.Pow(other.Z - this.Z, 2));
        }

        #region 重载
        public static Point3D operator +(Point3D left, Point3D right)
        {
            return new Point3D(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
        }
        public static Point3D operator +(Point3D left, Vector3D dir)
        {
            return new Point3D(left.X + dir.X, left.Y + dir.Y, left.Z + dir.Z);
        }
        public static Vector3D operator -(Point3D left, Point3D right)
        {
            return new Vector3D(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
        }
        public static Point3D operator -(Point3D left, Vector3D dir)
        {
            return new Point3D(left.X - dir.X, left.Y - dir.Y, left.Z - dir.Z);
        }
        public static Point3D operator -(Point3D point)
        {
            return new Point3D(-point.X, -point.Y, -point.Z);
        }
        public static Point3D operator *(Point3D point, double num)
        {
            return new Point3D(point.X * num, point.Y * num, point.Z * num);
        }
        public static Point3D operator /(Point3D point, double num)
        {
            return new Point3D(point.X / num, point.Y / num, point.Z / num);
        }

        public bool Equals(Point3D other)
        {
            return other.DistanceTo(this) <= SketchUpApplication.GlobalTolerance;
        }

        public override bool Equals(object obj)
        {
            if (obj is Point3D p)
            {
                return Equals(p);
            }
            else
            {
                return false;
            }
        }
        #endregion
    }
}